﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Linq;
using System.IO;
using System.Data;
using Microsoft.VisualBasic;
using Visifire.Charts;
using Visifire.Commons;
//using TestControl;

namespace proyecto
{
    public class data
    {
        private DataTable[] matrix;
        private int nTables;
        private bool [] tableCreated;
        private int nCols;
        private int nRows;
        private filter[] filters;


        private string[] classifications;
        public int nClass;
        public string[][] groupsLabels;
        public int[] ngroups;
        public int[][] groups;

        public double[] markingMin;
        public double[] markingMax;
        public int[] markingIndex;
        public bool ismarked;

        string[] name;

        public bool[] isInFilterRange;

        double[][] normalizedMatrix;

        double[][] statistics;

        int nSelected;
       

        public data(){
            nTables = 0;
            tableCreated = new bool[20];

            matrix = new DataTable[20];
            name = new string[20];

            for (int i=0; i<20; i++)
                tableCreated[i] = false;

            markingIndex = new int[2];

            markingMax = new double[2];

            markingMin = new double[2];

            ismarked = false;
        }

        public data(string tabulatedFile){
            
            //FileSystem.FileOpen(FileSystem.FreeFile(), tabulatedFile, OpenMode.Input, OpenAccess.Read);
            //StreamReader reader = new StreamReader(tabulatedFile);
            //FileSystem.FileOpen(FileSystem.FreeFile(), tabulatedFile, OpenMode.Input, OpenAccess.Read, default(OpenShare), default(Int32));
            //MessageBox.Show("Banderita");
            
            /*DataColumn column = new DataColumn("id", typeof(System.Int32));
            column.AutoIncrement = true;
            matrix.Columns.Add(column);*/

            matrix = new DataTable[20];

            nTables = 20;

            name = new string[20];

            tableCreated = new bool[20];

            tableCreated[0] = true;
            for (int i = 1; i < 20; i++)
            {
                tableCreated[i] = false;
            }

            markingIndex = new int[2];

            markingMax = new double[2];

            markingMin = new double[2];

            ismarked = false;

            DataTable auxTable = new DataTable();

            StreamReader reader;
            try
            {
                reader = new StreamReader(tabulatedFile);
            }
            catch
            {
                return;
            }

            string aux;

            try
            {
                aux = reader.ReadLine().Replace("/","_").Replace("-","_").Replace("\\","_");
            }
            catch
            {
                MessageBox.Show("Error while reading file: Empty file?");
                return;
            }

            while (aux[0] == '#')
            {
                try
                {
                    aux = reader.ReadLine().Replace("/", "_").Replace("-", "_").Replace("\\", "_"); ;
                }
                catch
                {
                    MessageBox.Show("Error while reading file: Invalid format file?");
                    return;
                }
            }

            bool titles;

            aux = aux.Replace(".CEL", "");
            aux = aux.Replace(".cel", "");

            string[] titlesString = aux.Split(' ', '\t');
            aux = titlesString[0];

            for (int i = 1; i < titlesString.Length; i++)
                aux = aux + " " + titlesString[i];

            columnsTitle titlesQuestion = new columnsTitle(aux);
            titlesQuestion.ShowDialog();

            titles = titlesQuestion.title();

            //aux = reader.ReadLine();
            string[] aux1 = aux.Split('\t' , ' ' , ';' , ',');
            nCols = aux1.Length;

            filters = new filter[nCols-1];

            if (titles)
            {
                DataColumn col = new DataColumn(aux1[0]/*,typeof(System.String)*/);
                //MessageBox.Show(aux1[0] + "de tipo string");
                //col.AutoIncrement = true;
                auxTable.Columns.Add(col);
            }

            else
            {
                DataColumn col = new DataColumn("c0");
                auxTable.Columns.Add(col);
            }


            for (int i = 1; i < nCols; i++)
            {
                string titleLabel;
                if (titles)
                    titleLabel = aux1[i];
                else
                    titleLabel = "c"+i.ToString();
                DataColumn column = new DataColumn(titleLabel/*, typeof (System.Double)*/);
                //MessageBox.Show(aux1[i] + "de tipo double");
                //column.AutoIncrement = true;
                auxTable.Columns.Add(column);



            }



            //MessageBox.Show("Banderita");
            

            //aux = reader.ReadToEnd();
            
            //string[] aux2 = aux.Split('\n');


            string[] aux2;

            if (titles)
                aux2 = reader.ReadToEnd().Trim().Split('\n');
            else
            {
                string[] auxLabel = reader.ReadToEnd().Trim().Split('\n');
                aux2 = new string[auxLabel.Length+1];
                aux2[0] = aux;
                for (int i = 1; i < aux2.Length; i++)
                    aux2[i] = auxLabel[i-1];
            }

            //MessageBox.Show(aux2[1]);

            nRows = 0;
            /*for (int i = 0; i < aux2.Length; i++)
            {
                //MessageBox.Show("i es " + i + " y la longitud es " + aux2.Length + " y la linea actual es " + aux2[i]);
                if (aux2[i] != "")
                if (aux2[i][0] != '#')
                    nRows++;
            }*/

            //nRows = aux2.Length;

            for (int j = 0; j<aux2.Length; j++){
                //MessageBox.Show("FILA "+j.ToString());
                if (aux2[j] == "") break;
                if (aux2[j][0] != '#')
                    nRows++;

                //MessageBox.Show(aux2[j]);
                while (aux2[j][0] == '#')
                    j++;

                String[] aux3 = aux2[j].Split('\t', ' ', ';', ',');

                //inicializamos filtros
                if (j==0)
                    for (int i = 0; i < nCols - 1; i++)
                    {
                        aux3[i + 1] = aux3[i + 1].Replace('.', ',');
                        //filters[i] = new filter(double.Parse(aux3[i + 1]), double.Parse(aux3[i + 1]));
                        
                    }
                DataRow row = auxTable.NewRow();
                //MessageBox.Show(aux3[0]);
                if (titles)
                    row[aux1[0]] = aux3[0];
                else
                    row["c0"] = aux3[0];
                //matrix[count][0] = aux2[0]; 

                for (int i = 1; i < nCols; i++)
                {
                    //MessageBox.Show(aux3[i]);

                    aux3[i]=aux3[i].Replace('.', ',');

                    //MessageBox.Show(aux3[i]);
                    if (titles)
                        row[aux1[i]] = double.Parse(aux3[i]);
                    else
                        row["c"+i.ToString()] = double.Parse(aux3[i]);
                    //MessageBox.Show(aux3[i] + " grabado como " + row[aux1[i]].ToString());

                    ////operaciones con filtros


                    /*if (double.Parse(aux3[i]) < filters[i - 1].getMin())
                    {
                        //MessageBox.Show("Filtro para " + i.ToString() + " cambiado a " + aux3[i].ToString() + " , " + filters[i - 1].getMax().ToString());
                        filters[i - 1].setMin(double.Parse(aux3[i]));
                    }
                    //else

                        if (double.Parse(aux3[i]) > filters[i - 1].getMax())
                        {
                            //MessageBox.Show("Filtro para " + i.ToString() + " cambiado a " + filters[i - 1].getMin().ToString() + " , " + aux3[i].ToString());
                            filters[i - 1].setMax(double.Parse(aux3[i]));
                        }
                    */
                }
                    //matrix[count][i-1] = float.Parse(aux2[i]);
                
                auxTable.Rows.Add(row);

                /*if (aux2[j+1] == "")
                    j++;*/
                
                
                
            }

            loadDataWindow loadData = new loadDataWindow(auxTable);
            //loadDataWindow loadData = new loadDataWindow();
            loadData.ShowDialog();

            if (!loadData.result())
            {
                nTables = 0;
                return;
            }
            
            matrix[0] = new DataTable("Data Matrix");
            name[0] = "Data Matrix";
            matrix[0].Locale = System.Globalization.CultureInfo.CurrentCulture;

            //DataTable

            for (int i = 0; i < nCols; i++)
            {
                DataColumn auxColumn = new DataColumn(loadData.getColumnTitle(i));
                switch (loadData.type(i))
                {
                    case "String":
                        auxColumn.DataType = typeof(string);
                        break;
                    case "Integer":
                        auxColumn.DataType = typeof(int);
                        break;
                    case "Boolean":
                        auxColumn.DataType = typeof(bool);
                        break;
                    case "Float":
                        auxColumn.DataType = typeof(double);
                        break;
                }
                matrix[0].Columns.Add(auxColumn);
            }

            nCols = loadData.getNCols();
            nRows = loadData.getNRows();

            isInFilterRange = new bool[nRows];

            for (int i = 0; i < nRows; i++)
            {
                DataRow auxRow = matrix[0].NewRow();


                isInFilterRange[i] = true;


                for (int j = 0; j < nCols; j++)
                {
                    //MessageBox.Show(loadData.type(j));
                    switch (loadData.type(j))
                    {
                        case "String":
                            
                            auxRow[j] = loadData.getData(i,j).Replace("-","_").Replace("/","_").Replace("\\","_");
                            break;
                        case "Integer":
                            auxRow[j] = int.Parse(loadData.getData(i, j));
                            break;
                        case "Boolean":
                            auxRow[j] = bool.Parse(loadData.getData(i, j));
                            break;
                        case "Float":
                            auxRow[j] = double.Parse(loadData.getData(i, j));
                            break;
                    }

                    if (loadData.type(j) == "Integer" || loadData.type(j) == "Float")
                    {
                        //MessageBox.Show("Entra");

                        if (i == 0)
                        {
                            

                            //aux3[i + 1] = aux3[i + 1].Replace('.', ',');
                            filters[j - 1] = new filter(double.Parse(auxRow[j].ToString()), double.Parse(auxRow[j].ToString()));
                            //MessageBox.Show("Filtro para " + j.ToString() + " fijado como " + auxRow[j].ToString() + " , " + auxRow[j].ToString());
                            //MessageBox.Show("Filtro para " + i.ToString() + " fijado como " + aux3[i + 1].ToString() + " , " + aux3[i + 1].ToString());
                        }
                        else
                        {
                            if (double.Parse(auxRow[j].ToString()) < double.Parse(filters[j - 1].getMin().ToString()))
                            {
                                //MessageBox.Show("Filtro para " + j.ToString() + " cambiado a " + auxRow[j].ToString() + " , " + filters[j - 1].getMax().ToString());
                                filters[j - 1].setMin(double.Parse(auxRow[j].ToString()));

                            }
                            //else

                            if (double.Parse(auxRow[j].ToString()) > filters[j - 1].getMax())
                            {
                                //MessageBox.Show("Filtro para " + j.ToString() + " cambiado a " + filters[j - 1].getMin().ToString() + " , " + auxRow[j].ToString());
                                filters[j - 1].setMax(double.Parse(auxRow[j].ToString()));
                                //MessageBox.Show("Filtro para " + i.ToString() + " fijado como " + aux3[i + 1].ToString() + " , " + aux3[i + 1].ToString());
                            }

                        }

                    }
                    
                }

                matrix[0].Rows.Add(auxRow);

            }

            for (int i = nCols - 1; i >= 0; i--)
            {
                if (!loadData.loadColumn(i))
                {
                    matrix[0].Columns.Remove(matrix[0].Columns[i].Caption);
                    nCols--;
                }
            }

            //MessageBox.Show(matrix.Rows.Count.ToString() + " , " + matrix.Columns.Count.ToString());
                    
            groups = new int[matrix[0].Rows.Count][];

            Experiment_Design design = new Experiment_Design(this);
            design.ShowDialog();

            if (!design.result())
            {
                nTables = 0;
                return;
            }

            if (design.result())
            {
                try
                {
                    load_EsperimentDesign(design);
                }
                catch
                {
                    MessageBox.Show("Error while creating experiment design");
                    nClass = 0;
                }
            }

            nSelected = nRows;

            //MessageBox.Show(statistics[0][0].ToString() + "-" + statistics[1][0]);
            
            
        }


        public void load_experiment_design(string file)
        {

            StreamReader reader = new StreamReader(file);

            string aux;

            aux = reader.ReadLine();

            string[] aux1 = aux.Split('\t', ' ', ';', ',');

            classifications = new string[aux1.Length - 1];
            for (int i = 1; i < aux1.Length; i++)
            {
                classifications[i-1] = aux1[i];
            }
            nClass = aux1.Length - 1;

            ngroups = new int[nClass];

            

            aux = reader.ReadToEnd();

            string[] aux2 = aux.Split('\n');

            

            string[][] aux3 = new string[nRows][];

            for (int i = 0; i < nRows; i++)
            {
                aux2[i] = aux2[i].Trim();
                aux3[i] = aux2[i].Split('\t', ' ', ';', ',');
            }

            groupsLabels = new string[nClass][];
            

            for (int i = 0; i < nRows; i++)
                groups[i] = new int[nClass];

            for (int i = 1; i <= nClass; i++)
            {
                int count = 1;
                string label = aux3[0][i];
                for (int j = 1; j < nRows; j++)
                {
                    bool different = true;
                    for (int l = j-1; l >= 0; l--)
                        if (aux3[j][i] == aux3[l][i])
                            different = false;

                    if (different)
                    {
                        count++;
                        label = label + ("\t" + aux3[j][i]);
                    }
                    
                }
                //MessageBox.Show(label);
                groupsLabels[i - 1] = label.Split('\t');
                ngroups[i-1] = count;
            }

            for (int i = 0; i < nRows; i++)
            {

                int row = 0;

                for (bool found = false; !found; row++)
                {
                    string[] temp = matrix[0].Rows[i][0].ToString().Split('.');
                    if (aux3[row][0] == temp[0])
                        found = true;
                }
                row--;

                for (int j = 0; j<nClass; j++){

                    int groupIndex = 0;

                    for (bool found = false; !found; groupIndex++)
                        if (aux3[row][j+1]==groupsLabels[j][groupIndex])
                            found=true;

                    groupIndex--;

                    groups[row][j] = groupIndex;
                }
            }
            





        }









        public int getnCols()
        {
            return nCols;
        }

        public int getnRows()
        {
            return nRows;
        }

        public string getColumnTittle(int table, int n){
            return matrix[table].Columns[n].Caption;
            
        }

        /*public DataSeries getData(int x, int y)
        {
            DataPoint p = new DataPoint();
            
            String [] aux = new String[nCols];

            DataSeries series = new DataSeries();

            DataRow[] currentRows = matrix.Select(getColumnTittle(x) + ">=" + filters[x - 1].getMin().ToString() + "AND" + getColumnTittle(x) + "<=" + filters[x - 1].getMax().ToString()+"AND"+getColumnTittle(y) + ">=" + filters[y - 1].getMin().ToString() + "AND" + getColumnTittle(y) + "<=" + filters[y - 1].getMax().ToString());

            for (int i = 0; i < currentRows.Length; i++)
            {
                p.XValue = double.Parse(string(currentRows[i].ItemArray[x]));
                p.YValue = double.Parse(currentRows[i].ItemArray[y]);
                series.DataPoints.Add(p);
            }

            return (series);

        }*/

        public double getData(int table, int x, int y)
        {
            return Convert.ToDouble(matrix[table].Rows[x].ItemArray[y+1]);
        }

        public string getRowName(int table, int row)
        {
            return Convert.ToString(matrix[table].Rows[row].ItemArray[0]);
        }

        public double getNormalizedData(int x, int y)
        {
            return normalizedMatrix[x][y];
        }

        public double getMin(int n)
        {
            return filters[n].getMin();
        }

        public double getMax(int n)
        {
            return filters[n].getMax();
        }

        public string values(int column, int nValues)
        {
            return filters[column].values(nValues);
        }

        public void setFilter(string column, double min, double max)
        {
            string column_ = column.Replace("guionalto", "-");
            int i = 0;
            for (; column_ != this.getColumnTittle(0, i); i++) ;      

            filters[i-1].setMax(max);
            filters[i-1].setMin(min);
        }

        public void changeClick(string column)
        {
            int i = 0;
            for (; column != this.getColumnTittle(0, i); i++) ;

            filters[i].changeClick();
        }

        public void setLeftRight(string column, double left, double right)
        {
            int i = 0;
            for (; column != this.getColumnTittle(0, i); i++) ;

            filters[i].setLeftRight(left, right);
        }

        public double getLeft(string column)
        {
            int i = 0;
            for (; column != this.getColumnTittle(0, i); i++) ;

            return filters[i].getLeft();
        }

        public double getRight(String column)
        {
            int i = 0;
            for (; column != this.getColumnTittle(0, i); i++) ;

            return filters[i].getRight();
        }

        public double getLeft(int i)
        {
           
            return filters[i].getLeft();
        }

        public double getRight(int i)
        {
            return filters[i].getRight();
        }

        public DataTable getTable(int i)
        {
            return matrix[i];
        }

        public DataRow getRow(int table, int i)
        {
            return matrix[table].Rows[i];
        }

        public DataColumn getColumn(int table, int i)
        {
            return matrix[table].Columns[i];
        }

        
        public void load_EsperimentDesign(Experiment_Design design)
        {

            nClass = design.getnClassif();

            classifications = new string[nClass];

            ngroups = new int[nClass];

            groupsLabels = new string[nClass][];

            for (int i = 0; i < nClass; i++)
            {
                
                ngroups[i] = design.getnGroups(i);
                groupsLabels[i] = new string[ngroups[i]];
                classifications[i] = design.getClassLabel(i);
                for (int j = 0; j < ngroups[i]; j++)
                {
                    groupsLabels[i][j] = design.getgroupLabel(i, j);
                    //MessageBox.Show(groupsLabels[i][j]);
                }
            }

            for (int i = 0; i < nCols-1; i++)
            {
                groups[i] = new int[nClass];
                for (int j = 0; j < nClass; j++)
                    groups[i][j] = design.getGroup(i, j);
            }
        
        
        
        }

        public void refreshFilters()
        {

            nSelected = nRows;

            for (int i = 0; i < nRows; i++)
            {
                isInFilterRange[i] = true;
                for (int j = 0; j <getnCols() - 1 && isInFilterRange[i]; j++)
                    if (getData(0, i, j) < getMin(j) || getData(0, i, j) > getMax(j))
                    {
                        isInFilterRange[i] = false;

                        nSelected--;
                        //if (i < 10) MessageBox.Show("fila " + i.ToString() + j.ToString() + " " + getMin(j).ToString() + " " + getMax(j).ToString());
                    }
            }
        }

        public int getNtables()
        {
            return nTables;
        }

        public bool isCreated(int i)
        {
            return tableCreated[i];
        }

        public string getTableName(int i)
        {
            return name[i];
        }



        /*public void createFilters()
        {
            for (int i = 1; i < nCols; i++)
            {
                CustomRangeSelectorControl.RangeSelectorControl f = new CustomRangeSelectorControl.RangeSelectorControl();
                f.Name = "filter_" + i;
                f.DelimiterForRange = ",";
                f.RangeValues = filters[i - 1].values(50);
                f.Range1 = filters[i - 1].getMin().ToString();
                f.Range2 = filters[i - 1].getMax().ToString();
                Window1.addFilter(f);
            }
        }*/

        public void normalizeData()
        {
            
            matrix[1] = new DataTable("NormalizedData");
            name[1] = "NormalizedData";
            matrix[1] = matrix[0].Clone();
            

            tableCreated[1] = true;

            for (int i = 0; i<nCols; i++)

            statistics = new double[2][];
            normalizedMatrix = new double[nRows][];

            statistics[0] = new double[nCols - 1];
            statistics[1] = new double[nCols - 1];

            //Calculate medias

            for (int i = 0; i < nCols - 1; i++)
            {
                double acumMedia = 0;
                double acumDesv = 0;

                for (int j = 0; j < nRows; j++)
                {
                    acumMedia = acumMedia + getData(0, j, i);
                    if (i > 0)
                        acumDesv = acumDesv + ((getData(0, j, i - 1) - statistics[0][i - 1]) * (getData(0, j, i - 1) - statistics[0][i - 1]));
                }

                statistics[0][i] = acumMedia / nRows;
                if (i > 0)
                    statistics[1][i - 1] = Math.Sqrt(acumDesv / nRows);

            }
            double acum = 0;
            for (int i = 0; i < nRows; i++)
                acum = acum + ((getData(0, i, nCols - 2) - statistics[0][nCols - 2]) * (getData(0, i, nCols - 2) - statistics[0][nCols - 2]));

            statistics[1][nCols - 2] = Math.Sqrt(acum / nRows);

            for (int i = 0; i < nRows; i++)
            {
                DataRow aux = matrix[1].NewRow();
                aux[0] = getRowName(0, i);
                //normalizedMatrix[i] = new double[nCols - 1];
                for (int j = 0; j < nCols - 1; j++)
                    aux[j+1] = (getData(0, i, j) - statistics[0][j]) / statistics[1][j];
                matrix[1].Rows.Add(aux);
            }

        }

        public void createCorrelationMatrix()
        {

            tableCreated[2] = true;
            matrix[2] = new DataTable();
            matrix[2] = matrix[0].Clone();
            name[2] = "Correlation Matrix";
            matrix[2].TableName = "Correlation Matrix";

            matrix[2].Columns[0].Caption = "Correlations";

            for (int i = 0; i < matrix[2].Columns.Count-1; i++)
            {
                DataRow row = matrix[2].NewRow();
                row[0] = matrix[2].Columns[i + 1].Caption;

                for (int j = 1; j < matrix[2].Columns.Count; j++)
                {

                    if (j == i + 1)
                        row[j] = 1;
                    if (j < i + 1)
                        row[j] = matrix[2].Rows[j-1][i+1];
                    if (j > i + 1)
                        row[j] = correlation(i + 1, j);
                }
                matrix[2].Rows.Add(row);
            }
        }

        public double correlation(int row, int column)
        {

            double x = 0, y = 0;

            for (int i = 0; i < nRows; i++)
            {
                x = x + Convert.ToDouble(matrix[0].Rows[i][row]);
                y = y + Convert.ToDouble(matrix[0].Rows[i][column]);
            }

            x = x / Convert.ToDouble(nRows);
            y = y / Convert.ToDouble(nRows);

            double xy = 0, deX = 0, deY = 0;

            for (int i = 0; i < nRows; i++)
            {

                xy = xy + Convert.ToDouble(matrix[0].Rows[i][row]) * Convert.ToDouble(matrix[0].Rows[i][column]);

                deX = deX + (Convert.ToDouble((Convert.ToDouble(matrix[0].Rows[i][row]) - x)) * Convert.ToDouble((Convert.ToDouble(matrix[0].Rows[i][row]) - x)));

                deY = deY + ((Convert.ToDouble(matrix[0].Rows[i][column]) - y) * (Convert.ToDouble(matrix[0].Rows[i][column]) - y));
            }

            xy = xy / nRows;
            deX = deX / nRows;
            deY = deY / nRows;

            xy = xy - x * y;
            deX = Math.Sqrt(deX);
            deY = Math.Sqrt(deY);

            return (xy / (deX * deY));

        }

        public void createTable(DataTable InputTable)
        {

            bool found = false;
            int i;
            for (i = 0; i < 20 && !found; i++)
            {

                if (!isCreated(i) && i > 2)
                    found = true;
            }

            i--;

            matrix[i] = new DataTable();

            matrix[i] = InputTable.Clone();

            for (int j = 0; j < nRows; j++)
            {
                DataRow row = matrix[i].NewRow();
                for (int k = 0; k < nCols; k++)
                    row[k] = InputTable.Rows[j][k];
                matrix[i].Rows.Add(row);
            }

            matrix[i].TableName = InputTable.TableName;

            name[i] = matrix[i].TableName;

            tableCreated[i] = true;

            nTables++;
        }

        public void increaseCols()
        {

            nCols++;

            double[] lefts = new double[nCols];
            double[] rights = new double[nCols];
            double[] mins = new double[nCols];
            double[] maxs = new double[nCols];

            int nfilters = filters.Length;

            for (int i = 0; i < nfilters; i++)
            {

                lefts[i] = filters[i].getLeft();
                rights[i] = filters[i].getRight();
                mins[i] = filters[i].getMin();
                maxs[i] = filters[i].getMax();
            }

            double newLeft = Convert.ToDouble(matrix[0].Rows[0][nCols-1]);
            double newRight = Convert.ToDouble(matrix[0].Rows[0][nCols-1]);

            for (int i = 0; i < nRows; i++)
            {

                if (Convert.ToDouble(matrix[0].Rows[i][nCols - 1]) < newLeft)
                    newLeft = Convert.ToDouble(matrix[0].Rows[i][nCols - 1]);

                if (Convert.ToDouble(matrix[0].Rows[i][nCols - 1]) > newRight)
                    newRight = Convert.ToDouble(matrix[0].Rows[i][nCols - 1]);
            }

            filters = new filter[nfilters + 1];

            for (int i = 0; i < nfilters; i++)
            {
                filters[i] = new filter();
                filters[i].setLeftRight(lefts[i], rights[i]);
                filters[i].setMax(maxs[i]);
                filters[i].setMin(mins[i]);
            }

            filters[nfilters] = new filter(newLeft, newRight);


            
        }

        public int getnFilters()
        {

            return filters.Length;
        }

        public void AddTable(DataTable table, int cols, int rows)
        {

            nCols = cols;

            nRows = rows;

            int index = 0;

            for (; tableCreated[index] && index != 2; index++) { ;}



            matrix[index] = new DataTable();

            matrix[index] = table.Clone();

            matrix[index].TableName = table.TableName;

            name[index] = table.TableName;

            for (int i = 0; i < nRows; i++)
            {
                DataRow row = matrix[index].NewRow();
                for (int j = 0; j < nCols; j++)
                    row[j] = table.Rows[i][j];
                matrix[index].Rows.Add(row);
            }

            tableCreated[index] = true;

            nTables++;

        }

        public void createFilters()
        {

            isInFilterRange = new bool[nRows];

            for (int i = 0; i < nRows; i++)
                isInFilterRange[i] = true;

            filters = new filter[nCols - 1];

            for (int i = 1; i < nCols; i++)
                filters[i - 1] = new filter(Convert.ToDouble(matrix[0].Rows[0][i]), Convert.ToDouble(matrix[0].Rows[0][i]));


            for (int i = 1; i < nRows; i++)
            {

                for (int j = 1; j < nCols; j++)
                {

                    if (Convert.ToDouble(matrix[0].Rows[i][j]) < filters[j - 1].getMin()) filters[j - 1].setMin(Convert.ToDouble(matrix[0].Rows[i][j]));
                    if (Convert.ToDouble(matrix[0].Rows[i][j]) > filters[j - 1].getMax()) filters[j - 1].setMax(Convert.ToDouble(matrix[0].Rows[i][j]));
                }
            }
        }

        public string getCluster(int table)
        {

            DataTable newTable = matrix[table].Clone();

            for (int i = 0; i<matrix[table].Rows.Count; i++)
                if (isInFilterRange[i])
                {
                    DataRow newRow = newTable.NewRow();
                    for (int j = 0; j < matrix[table].Columns.Count; j++)
                        newRow[j] = matrix[table].Rows[i][j];
                    newTable.Rows.Add(newRow);
                }

            try
            {
                //MessageBox.Show("pita");
                R_Application rApp = new R_Application();

                return rApp.clustering(newTable);
            }
            catch
            {
                MessageBox.Show("Unable to connect R");
                return ("");
            }

        }

        public int getNSelected()
        {
            return nSelected;
        }

                    

    }
}
